00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef GOSS_PARSER_HPP_
00014 #define GOSS_PARSER_HPP_
00015
00016 #define OLD_MAP
00017
00018 #include <iostream>
00019 #include <string>
00020 #include <vector>
00021 #include <map>
00022 #ifndef OLD_MAP
00023 #include <boost/unordered_map.hpp>
00024 #endif
00025
00026 #include <boost/property_tree/ptree.hpp>
00027 #include <boost/property_tree/xml_parser.hpp>
00028 #include <boost/algorithm/string/split.hpp>
00029 #include <boost/algorithm/string/classification.hpp>
00030 #include <boost/algorithm/string/predicate.hpp>
00031 #include <boost/foreach.hpp>
00032 #include <boost/shared_ptr.hpp>
00033
00034 #include "gridpack/component/base_component.hpp"
00035 #include "gridpack/timer/coarse_timer.hpp"
00036 #include "gridpack/component/data_collection.hpp"
00037 #include "gridpack/parser/dictionary.hpp"
00038 #include "gridpack/utilities/exception.hpp"
00039 #include "gridpack/network/base_network.hpp"
00040 #include "gridpack/parser/base_parser.hpp"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 namespace gridpack {
00064 namespace parser {
00065
00066 template <class _network>
00067 class GOSS_parser : BaseParser<_network>
00068 {
00069 public:
00070
00071 enum XML_TYPE {INTEGER, BOOLEAN, DOUBLE, CHARACTER, STRING, N_TYPES};
00072
00073
00074 explicit GOSS_parser(boost::shared_ptr<_network> network) :
00075 p_network(network), nBuses(0), nBranches(0) , totalGenerators(0),
00076 totalLines(0), totalTransformers(0), totalLoads(0), p_case_sbase(0.0),
00077 p_case_id(0), p_configExists(false)
00078 {
00079 this->setNetwork(network);
00080 p_comm = network->communicator();
00081 }
00082
00083
00084
00085
00086
00087 virtual ~GOSS_parser(){}
00088
00089
00090
00091
00092
00093 virtual void parse(const std::string & xmlFileName)
00094 {
00095 p_timer = gridpack::utility::CoarseTimer::instance();
00096 p_timer->configTimer(false);
00097 int t_total = p_timer->createCategory("Parser:Total Elapsed Time");
00098 p_timer->start(t_total);
00099
00100 boost::property_tree::ptree xmlTree;
00101
00102 try {
00103 setupXMLTree(xmlFileName, xmlTree);
00104 } catch (boost::property_tree::xml_parser_error & e) {
00105 std::cout << "ERROR IN PARSER SETUP" << std::endl;
00106 throw e;
00107 }
00108
00109 setTypeAssociations(xmlTree);
00110 loadCase(xmlTree);
00111 loadBusData(xmlTree);
00112 loadBranchData(xmlTree);
00113 this->createNetwork(p_busCollection, p_branchCollection);
00114 p_timer->stop(t_total);
00115 p_timer->configTimer(true);
00116 }
00117
00118 int getNBuses() {return nBuses;};
00119 int getCaseId() {return p_case_id;};
00120 int getNBranches() {return nBranches;};
00121 double getCaseSbase() {return p_case_sbase;};
00122
00123 void copyDataCollection(std::vector<boost::shared_ptr
00124 <gridpack::component::DataCollection> > & busCollection,
00125 std::vector<boost::shared_ptr
00126 <gridpack::component::DataCollection> > & branchCollection)
00127 {
00128 busCollection = p_busCollection;
00129 branchCollection = p_branchCollection;
00130 }
00131
00132 void test_dumpDataColletionVector(std::vector
00133 <boost::shared_ptr<gridpack::component::DataCollection> >
00134 & dataCollectionVector)
00135 {
00136 std::vector<boost::shared_ptr<gridpack::component::DataCollection> >::iterator
00137 dataCollection;
00138 for (dataCollection = dataCollectionVector.begin();
00139 dataCollection != dataCollectionVector.end(); ++dataCollection)
00140 {
00141 (*dataCollection)->dump();
00142 }
00143 }
00144
00145 void test_dumpDataColletion(gridpack::component::DataCollection & dataCollection)
00146 {
00147 dataCollection.dump();
00148 }
00149
00150 void test_dumpTypeMap()
00151 {
00152 typename std::map<std::string, XML_TYPE>::iterator type;
00153 for (type = typeMap.begin(); type != typeMap.end(); ++type)
00154 {
00155 std::cout << "<" << type->first << "; ";
00156 if (type->second == BOOLEAN) {
00157 std::cout << "boolean>" << std::endl;
00158 } else if (type->second == DOUBLE) {
00159 std::cout << "double>" << std::endl;
00160 } else if (type->second == INTEGER) {
00161 std::cout << "integer>" << std::endl;
00162 } else if (type->second == STRING) {
00163 std::cout << "string>" << std::endl;
00164 } else if (type->second == CHARACTER) {
00165 std::cout << "character>" << std::endl;
00166 }
00167 }
00168 }
00169
00170 protected:
00171
00172
00173
00174
00175
00176 private:
00177
00178 void setupXMLTree(const std::string & xmlFileName,
00179 boost::property_tree::ptree & xmlTree)
00180 {
00181 if (p_comm.rank() != 0) return;
00182 try {
00183 read_xml(xmlFileName, xmlTree);
00184 } catch (boost::property_tree::xml_parser_error & e) {
00185 throw e;
00186 }
00187 }
00188
00189
00190
00191
00192
00193
00194 void setTypeAssociations(boost::property_tree::ptree & xmlTree)
00195 {
00196 if (p_comm.rank() != 0) return;
00197 std::string name("");
00198 boost::property_tree::ptree schemaStyleAttr;
00199
00200 try {
00201 schemaStyleAttr =
00202 xmlTree.get_child("application.grammars.xs:schema");
00203 } catch (boost::exception & e){
00204 std::cout << __FILE__ << ":" << __LINE__ <<
00205 "\n\tThrowing exception from get_child(\"application.grammars.xs:schema\")"
00206 << std::endl;
00207 throw;
00208 }
00209
00210 typeMap["mrid"] = STRING;
00211 typeMap["elementIndex"] = INTEGER;
00212
00213 BOOST_FOREACH( boost::property_tree::ptree::value_type const& elementAttr,
00214 schemaStyleAttr)
00215 {
00216 try {
00217 recursiveSetTypeAssociation(elementAttr, name);
00218 } catch (boost::exception & e) {
00219 std::cout << __FILE__ << ":" << __LINE__ <<
00220 "\n\tError in recursive type setting "
00221 << name << std::endl;
00222 }
00223 }
00224 }
00225
00226 void recursiveSetTypeAssociation(boost::property_tree::ptree::value_type
00227 const& elementType, std::string & name)
00228 {
00229 XML_TYPE typeEnum;
00230
00231 if (elementType.first == "xs:element") {
00232
00233 const boost::property_tree::ptree & attributes
00234 = elementType.second.get_child("<xmlattr>");
00235
00236
00237 BOOST_FOREACH( boost::property_tree::ptree::value_type const& attr,
00238 attributes)
00239 {
00240 if (attr.first == "name") {
00241 name = attr.second.data() ;
00242 } else if (attr.first == "type"){
00243 std::string type = attr.second.data();
00244 std::vector<std::string> split_type;
00245 boost::algorithm::split(split_type, type,
00246 boost::algorithm::is_any_of(":"), boost::token_compress_on);
00247 if (split_type[0] == "xs"){
00248 if (split_type[1] == "int") {
00249 typeEnum = INTEGER;
00250 } else if (split_type[1] == "boolean") {
00251 typeEnum = BOOLEAN;
00252 } else if (split_type[1] == "double") {
00253 typeEnum = DOUBLE;
00254 } else if (split_type[1] == "char") {
00255 typeEnum = CHARACTER;
00256 } else if (split_type[1] == "string") {
00257 typeEnum = STRING;
00258 } else {
00259 typeEnum = N_TYPES;
00260 }
00261 if (typeEnum < N_TYPES) {
00262 typeMap[name] = typeEnum;
00263 }
00264 }
00265 }
00266 }
00267 } else {
00268 std::string element = elementType.first;
00269 boost::property_tree::ptree subTree;
00270 try {
00271 subTree = elementType.second.get_child("");
00272 } catch (boost::exception & e) {
00273 std::cout << __FILE__ << ":" << __LINE__ <<
00274 "\n\tError in recursive statement " << element
00275 << std::endl;
00276 throw;
00277 }
00278 BOOST_FOREACH( boost::property_tree::ptree::value_type
00279 const& subTreeType, subTree)
00280 {
00281 recursiveSetTypeAssociation(subTreeType, name);
00282 }
00283 }
00284
00285 }
00286
00287
00288
00289
00290
00291
00292 void loadCase(boost::property_tree::ptree & xmlTree)
00293 {
00294 if (p_comm.rank() == 0) {
00295 boost::property_tree::ptree caseXMLTree =
00296 xmlTree.get_child("GridpackPowergrid");
00297
00298
00299 BOOST_FOREACH( boost::property_tree::ptree::value_type
00300 const& caseAttr, caseXMLTree)
00301 {
00302 if (caseAttr.first == "CASE_SBASE")
00303 {
00304 p_case_sbase = atof(caseAttr.second.data().c_str());
00305 }
00306 if (caseAttr.first == "CASE_ID")
00307 {
00308 p_case_id = atoi(caseAttr.second.data().c_str());
00309 }
00310 }
00311 }
00312
00313
00314 double sval = p_case_sbase;
00315 double rval;
00316 MPI_Comm comm = static_cast<MPI_Comm>(p_network->communicator());
00317 int nprocs = p_network->communicator().size();
00318 int ierr = MPI_Allreduce(&sval,&rval,1,MPI_DOUBLE,MPI_SUM,comm);
00319 p_case_sbase = rval;
00320 this->setCaseSBase(p_case_sbase);
00321 int isval, irval;
00322 isval = p_case_id;
00323 ierr = MPI_Allreduce(&isval,&irval,1,MPI_INT,MPI_SUM,comm);
00324 p_case_id = irval;
00325 this->setCaseID(p_case_id);
00326 }
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 void loadBusData(boost::property_tree::ptree & xmlTree)
00338 {
00339 if (p_comm.rank() != 0) return;
00340 boost::property_tree::ptree busXMLTree =
00341 xmlTree.get_child("GridpackPowergrid.Buses");
00342
00343
00344
00345 BOOST_FOREACH( boost::property_tree::ptree::value_type
00346 const& busTree, busXMLTree)
00347 {
00348 readBus(busTree);
00349 }
00350 #if 0
00351 boost::shared_ptr<gridpack::component::DataCollection>
00352 data(new gridpack::component::DataCollection);
00353 data->addValue("N_GENERATORS", totalGenerators);
00354 data->addValue("N_LOADS", totalLoads);
00355 p_busCollection.push_back(data);
00356 #endif
00357
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 void readBus(boost::property_tree::ptree::value_type const & busTree)
00375 {
00376 boost::shared_ptr<gridpack::component::DataCollection>
00377 data(new gridpack::component::DataCollection);
00378
00379 int nLoads = 0;
00380 int nGenerators = 0;
00381
00382 BOOST_FOREACH( boost::property_tree::ptree::value_type busAttr,
00383 busTree.second)
00384 {
00385 if (busAttr.first == "Generators")
00386 {
00387 BOOST_FOREACH( boost::property_tree::ptree::value_type genSet,
00388 busAttr.second)
00389 {
00390 BOOST_FOREACH( boost::property_tree::ptree::value_type genAttr,
00391 genSet.second)
00392 {
00393 loadCollection(data, genAttr, nGenerators);
00394 }
00395 ++nGenerators;
00396 }
00397
00398 } else if (busAttr.first == "Loads") {
00399
00400 BOOST_FOREACH( boost::property_tree::ptree::value_type loadSet,
00401 busAttr.second)
00402 {
00403 BOOST_FOREACH( boost::property_tree::ptree::value_type loadAttr,
00404 loadSet.second)
00405 {
00406 loadCollection(data, loadAttr, nLoads);
00407 }
00408 ++nLoads;
00409 }
00410
00411 } else {
00412 loadCollection(data, busAttr);
00413 }
00414 }
00415 data->addValue("GENERATOR_NUMBER", nGenerators);
00416 data->addValue("LOADS_NUMBER", nLoads);
00417 p_busCollection.push_back(data);
00418 ++nBuses;
00419
00420 totalGenerators += nGenerators;
00421 totalLoads += nLoads;
00422 }
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433 void loadBranchData(boost::property_tree::ptree & xmlTree)
00434 {
00435 if (p_comm.rank() != 0) return;
00436 boost::property_tree::ptree branchXMLTree =
00437 xmlTree.get_child("GridpackPowergrid.Branches");
00438
00439
00440
00441 BOOST_FOREACH( boost::property_tree::ptree::value_type const& branchTree,
00442 branchXMLTree)
00443 {
00444 readBranch(branchTree);
00445 }
00446 #if 0
00447 boost::shared_ptr<gridpack::component::DataCollection>
00448 data(new gridpack::component::DataCollection);
00449 data->addValue("N_TRANSFORMERS", totalTransformers);
00450 data->addValue("N_LINES", totalLines);
00451 p_branchCollection.push_back(data);
00452 #endif
00453 }
00454
00455 void readBranch(boost::property_tree::ptree::value_type const & branchTree)
00456 {
00457 boost::shared_ptr<gridpack::component::DataCollection>
00458 data(new gridpack::component::DataCollection);
00459 int nTransformers = 0;
00460 int nLines = 0;
00461
00462 BOOST_FOREACH( boost::property_tree::ptree::value_type branchAttr,
00463 branchTree.second)
00464 {
00465
00466 std::cout << "Branch attr = " << branchAttr.first << std::endl;
00467 if (branchAttr.first == "TransmissionElements")
00468 {
00469 BOOST_FOREACH( boost::property_tree::ptree::value_type transAttr,
00470 branchAttr.second)
00471 {
00472 if (transAttr.first == "Line")
00473 {
00474 BOOST_FOREACH( boost::property_tree::ptree::value_type lineSet,
00475 transAttr.second)
00476 {
00477 loadCollection(data, lineSet, nLines);
00478 }
00479 ++nLines;
00480 } else if (transAttr.first == "Transformer")
00481 {
00482 BOOST_FOREACH( boost::property_tree::ptree::value_type transformerSet,
00483 transAttr.second)
00484 {
00485 loadCollection(data, transformerSet, nTransformers);
00486 }
00487 ++nTransformers;
00488 }
00489 }
00490 } else
00491 loadCollection(data, branchAttr);
00492 }
00493 data->addValue("LINE_NUMBER", nLines);
00494 data->addValue("TRANSFORMER_NUMBER", nTransformers);
00495 totalLines += nLines;
00496 totalTransformers += nTransformers;
00497 p_branchCollection.push_back(data);
00498 ++nBranches;
00499 }
00500
00501
00502
00503
00504
00505
00506
00507 void loadCollection(boost::shared_ptr<gridpack::component::DataCollection> & data,
00508 boost::property_tree::ptree::value_type & attr)
00509 {
00510 XML_TYPE type = typeMap[attr.first];
00511
00512 switch (type)
00513 {
00514 case BOOLEAN:
00515 {
00516 bool value = true;
00517 if (attr.second.data() == "false") value = false;
00518 data->addValue(attr.first.c_str(), value);
00519 break;
00520 }
00521 case INTEGER:
00522 {
00523 data->addValue(attr.first.c_str(), atoi(attr.second.data().c_str()));
00524 break;
00525 }
00526 case DOUBLE:
00527 {
00528 data->addValue(attr.first.c_str(), atof(attr.second.data().c_str()));
00529 break;
00530 }
00531 case CHARACTER:
00532 {
00533 data->addValue(attr.first.c_str(), attr.second.data()[0]);
00534 break;
00535 }
00536 case STRING:
00537 {
00538 data->addValue(attr.first.c_str(), attr.second.data().c_str());
00539 break;
00540 }
00541 default:
00542 {
00543 break;
00544 }
00545 }
00546 }
00547
00548 void loadCollection(boost::shared_ptr<gridpack::component::DataCollection> & data,
00549 boost::property_tree::ptree::value_type & attr, int nElems)
00550 {
00551 XML_TYPE type = typeMap[attr.first];
00552
00553 switch (type)
00554 {
00555 case BOOLEAN:
00556 {
00557 bool value = true;
00558 if (attr.second.data() == "false") value = false;
00559 data->addValue(attr.first.c_str(), value, nElems);
00560 break;
00561 }
00562 case INTEGER:
00563 {
00564 data->addValue(attr.first.c_str(), atoi(attr.second.data().c_str()),
00565 nElems);
00566 break;
00567 }
00568 case DOUBLE:
00569 {
00570 data->addValue(attr.first.c_str(), atof(attr.second.data().c_str()), nElems);
00571 break;
00572 }
00573 case CHARACTER:
00574 {
00575 data->addValue(attr.first.c_str(), attr.second.data()[0], nElems);
00576 break;
00577 }
00578 case STRING:
00579 {
00580 data->addValue(attr.first.c_str(), attr.second.data().c_str(), nElems);
00581 break;
00582 }
00583 default:
00584 {
00585 break;
00586 }
00587 }
00588 }
00589
00590
00591
00592
00593
00594
00595 boost::shared_ptr<_network> p_network;
00596
00597 int nBuses;
00598 int nBranches;
00599 int totalGenerators;
00600 int totalLines;
00601 int totalLoads;
00602 int totalTransformers;
00603
00604
00605 std::vector<boost::shared_ptr<gridpack::component::DataCollection> >
00606 p_busCollection;
00607 std::vector<boost::shared_ptr<gridpack::component::DataCollection> >
00608 p_branchCollection;
00609 std::map<std::string, XML_TYPE> typeMap;
00610
00611 parallel::Communicator p_comm;
00612 int p_case_id;
00613 double p_case_sbase;
00614 gridpack::utility::CoarseTimer *p_timer;
00615 bool p_configExists;
00616 };
00617
00618 }
00619 }
00620
00621 #endif